package com.xinghen.common.zookeeper.registry;

import com.google.common.base.Charsets;
import com.google.common.collect.Maps;
import com.google.common.hash.HashCode;
import com.google.common.hash.Hasher;
import com.google.common.hash.Hashing;
import com.xinghen.common.base.properties.XinghenCloudProperties;
import com.xinghen.common.base.properties.ZookeeperProperties;
import com.xinghen.common.zookeeper.generator.impl.IncrementIdGenerator;
import com.xinghen.common.zookeeper.registry.base.RegistryCenter;
import com.xinghen.common.zookeeper.registry.base.RegistryInfo;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.util.Objects;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeoutException;

/**
 * @author xinghen
 * @ClassName: RegistryCenterFactory
 * @Package: com.xinghen.common.zookeeper.registry
 * @Description 注册中心工厂
 * @create 2018-04-12 10:26
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@Slf4j
public class RegistryCenterFactory {

    private static final ConcurrentMap<HashCode, RegistryCenter> REG_CENTER_REGISTRY = Maps.newConcurrentMap();

    /**
     * 创建注册中心
     *
     * @param properties
     * @return
     */
    public static RegistryCenter createRegistryCenter(ZookeeperProperties properties) throws Exception {
        Hasher hasher = Hashing.md5().newHasher().putString(properties.getZkAddressList(), Charsets.UTF_8);
        HashCode code = hasher.hash();
        RegistryCenter registryCenter = REG_CENTER_REGISTRY.get(code);
        if (Objects.nonNull(registryCenter)) {
            return registryCenter;
        }
        try {
            registryCenter = new RegistryCenter(properties);
            registryCenter.init();
        } catch (Exception e) {
            log.error("无法连接到zookeeper", e.getMessage());
            throw new TimeoutException(e.getMessage());
        }
        REG_CENTER_REGISTRY.put(code, registryCenter);
        return registryCenter;
    }

    /**
     * 启动注册中心
     *
     * @param properties
     * @param host
     * @param app
     */
    public static void startUp(XinghenCloudProperties properties, String host, String app) {
        try {
            RegistryCenter registryCenter = createRegistryCenter(properties.getZookeeper());
            RegistryInfo registryInfo = new RegistryInfo(app, host, registryCenter);
            Long serviceId = new IncrementIdGenerator(registryInfo).nextId();
            IncrementIdGenerator.setServiceId(serviceId);
        } catch (Exception e) {
            log.error("zookeeper未启用，请检查配置是否正确");
        }
    }

}
